<?php
abstract class RCMSApplication {
	protected $request = null;
	protected $response = null;
	protected $session = null;
	protected $dbManager = null;
	protected $twig = null;
	protected $debug = false;
	protected $routers = array();
	protected $menus = array();
	
	public function __construct($debug = false) {
		$this->setDebugMode($debug);
		$this->initialize();
		$this->configure();
	}

	protected function initialize() {
		$this->request   = new RCMSRequest();
		$this->response  = new RCMSResponse();
		$this->session   = new RCMSSession();
		$this->dbManager = new RCMSDbManager();
	}

	protected function configure(){
	}

	protected function setDebugMode($debug) {
		$this->debug = $debug;
		if ($debug) {
			ini_set('display_errors', 1);
			error_reporting(-1);
			//set_error_handler("RCMSApplication::error_handler", E_ALL );
		} else {
			ini_set('display_errors', 0);
		}
	}

	public function isDebugMode(){
		return $this->debug;
	}

	public function getRequest(){
		return $this->request;
	}

	public function getResponse(){
		return $this->response;
	}

	public function getSession(){
		return $this->session;
	}

	public function getDbManager(){
		return $this->dbManager;
	}

	public function getViewDir(){
		return RCMS_PRIVATE_ROOT. '/view';
	}

	public function getViewCharset(){
		return 'UTF-8';
	}

	public function templateEngine(){
		if ($this->twig === null) {
			require_once RCMS_TEMPLATE_ENGINE_ROOT."/Autoloader.php";
			Twig_Autoloader::register();
			$loader = new Twig_Loader_Filesystem(array($this->getViewDir(), RCMS_FRAMEWORK_ROOT.'/view',));
			$this->twig = new Twig_Environment($loader,array(
				'strict_variables'    => true,
			    'cache' => $this->getViewDir().'_c',
				'debug'               => $this->isDebugMode(),
			    'charset'             => $this->getViewCharset(),
			    'base_template_class' => 'Twig_Template',
			    'autoescape'          => false,
			    'auto_reload'         => null,
			//'optimizations'       => -1,
			));
			$this->twig->addTest('subpath',new Twig_Test_Function('rcms_test_subpath'));
		}
		return $this->twig;
	}

	public function getRoutes() {
		if (sizeof($this->routers)==0) {
			$columns = array(
			'ROUTE_ID',
			'REQ_TYPE',
			'REQ_URL',
			'REQ_CTRL',
			'REQ_ACTION',
			'REQ_PARAMS',
			'PARSED_URL',
			'PARSED_MAP',
			);
			$whereClause = array(
				'SYSTEM_ID=:SYSTEM_ID', 
				'SUBSYS_ID=:SUBSYS_ID',
				'SYSTEM_LANG=:SYSTEM_LANG',
				'R_DEL_FLG <>\'1\''
			);
			$orderClause = array('ROUTE_ID ASC');
			$params = array(
				'SYSTEM_ID'=> $this->getSession()->get('SYSTEM_ID', '00'), 
				'SUBSYS_ID'=>$this->getSession()->get('SUBSYS_ID', '00'),
				'SYSTEM_LANG'=>$this->getSession()->get('SYSTEM_LANG', '*'),
			);
			$dao = $this->getDbManager()->getDAO('RcmsTable');
			$results = $dao->fetchAllDataByTableName('RCMS_ROUTE', $columns, $whereClause, $orderClause, $params);
			foreach ($results as $result) {
				$this->routers[] = new RCMSRouter($result);
			}
		}
		return $this->routers;
	}

	public function getMenus() {
		if (sizeof($this->menus)==0) {
			$columns = array(
			'MENU_ID',
			'MENU_PARENT_ID',
			'MENU_GROUP_NAME',
			'MENU_TYPE',
			'MENU_NAME',
			'MENU_TITLE',
			'MENU_DISP_FLG',
			'DISP_ORDER',
			'PARSED_DEEP',
			'PARSED_PATH',
			);
			$whereClause = array(
				'SYSTEM_ID=:SYSTEM_ID', 
				'SUBSYS_ID=:SUBSYS_ID',
				'SYSTEM_LANG=:SYSTEM_LANG',
				'R_DEL_FLG <>\'1\'',
			);
			$orderClause = array('DISP_ORDER ASC');
			$params = array(
				'SYSTEM_ID'=> $this->getSession()->get('SYSTEM_ID', '00'), 
				'SUBSYS_ID'=>$this->getSession()->get('SUBSYS_ID', '00'),
				'SYSTEM_LANG'=>$this->getSession()->get('SYSTEM_LANG', '*'),
			);
			$dao = $this->getDbManager()->getDAO('RcmsTable');
			$results = $dao->fetchAllDataByTableName('RCMS_MENU', $columns, $whereClause, $orderClause, $params);
			foreach ($results as $result) {
				$this->menus[] = new RCMSMenu($result);
			}
		}
		return $this->menus;
	}
	protected  function routing($request) {
		$urlPath = $request->getPathInfo();
		foreach ($this->getRoutes() as $route) {
			$r = $route->routing($urlPath);
			if (!is_null($r)) {
				return $r;
			}
		}
		throw new RuntimeException('not found router for '.$urlPath);
	}

	public function run(){
		try {
			$admin=new RCMSAdminCtrl($this);
			//$admin->recompileAllRoute();
			//$admin->recompileAllMenu();
			
			$route = $this->routing($this->getRequest());
			$controlClassName = ucfirst($route['ctrl']).'Ctrl';
			$actionMethodName = lcfirst($route['action']).'Action';
			$controller = new $controlClassName($this);
			if (!method_exists($controller, $actionMethodName)) {
				throw new RuntimeException("not found action $controlClassName.$actionMethodName for ".$this->getRequest()->getPathInfo());
			}
			$controller->run($actionMethodName, $route['params']);
			$contents = $controller->getContents();
			$template = $this->templateEngine()->loadTemplate($contents['site_template']);
			echo $template->render($contents);
			//$template->display($contents);
		} catch (Exception $e) {
			if ($this->isDebugMode()) {
				RCMSLog::trace($e);
			}
		}
	}


}

function rcms_test_subpath($path, $parent){
	if ($path == $parent) return true;
	return (0=== strpos($path, $parent.'/'));
}


?>